#include "stdafx.h"

    namespace network
    {
        namespace buffer
        {

            BasicBuffer::BasicBuffer() :
            m_id(0),
            SharedConstBuffer(0)
            {
            }

            BasicBuffer::BasicBuffer(boost::uint16_t _size)
            : SharedConstBuffer(_size + sizeof (boost::uint16_t) + sizeof (boost::uint16_t)),
            m_id(0)
            {
                m_offset = sizeof (boost::uint16_t);
            }

            BasicBuffer::BasicBuffer(boost::uint16_t _size, boost::uint16_t _id)
            : SharedConstBuffer(_size + sizeof (boost::uint16_t) + sizeof (boost::uint16_t)),
            m_id(_id)
            {
                BOOST_ASSERT((sizeof (boost::uint16_t) + m_offset) <= m_size);
                put_at_offset(&_id, sizeof (boost::uint16_t), sizeof (boost::uint16_t));
                m_offset = 2 * sizeof (boost::uint16_t);
            }

            BasicBuffer::BasicBuffer(boost::shared_ptr< std::vector<unsigned char> >& _data)
            : SharedConstBuffer(_data, utils::_get_from_uchar<boost::uint16_t>(&((*_data)[0])))
            {
                //std::cout << " buffer : " << std::endl;
                //for( std::vector< unsigned char >::iterator it_buf = (*_data).begin() ; it_buf != (*_data).end(); it_buf++)
                //	std::cout << (*it_buf);
                //std::cout << std::endl;

                get_at_offset(&m_id, sizeof (boost::uint16_t), sizeof (boost::uint16_t));
                m_offset = 2 * sizeof (boost::uint16_t);
            }

            /** construct with a std::vector of char encapsulated into a shared_ptr in order to
             * reconstruct packet when receiving... prefer the make method to construct packet
             */
            BasicBuffer::BasicBuffer(boost::shared_ptr< std::vector<unsigned char> >& _data, boost::uint16_t _size)
            : SharedConstBuffer(_data, _size)
            {
                //std::cout << " buffer : " << std::endl;
                //for( std::vector< unsigned char >::iterator it_buf = (*_data).begin() ; it_buf != (*_data).end(); it_buf++)
                //	std::cout << (*it_buf);
                //std::cout << std::endl;

                get_at_offset(&m_id, sizeof (boost::uint16_t), sizeof (boost::uint16_t));
                m_offset = 2 * sizeof (boost::uint16_t);
            }

            BasicBuffer::BasicBuffer(std::string _data)
            : SharedConstBuffer(_data.size() + sizeof (boost::uint16_t) + sizeof (boost::uint16_t))
            {
                BOOST_ASSERT((sizeof (boost::uint16_t) + m_offset) <= m_size);
                put_at_offset(_data.c_str(), _data.size(), 2 * sizeof (boost::uint16_t));

            }

            BasicBuffer::BasicBuffer(std::string _data, boost::uint16_t _size)
            : SharedConstBuffer(_size + sizeof (boost::uint16_t) + sizeof (boost::uint16_t))
            {
                BOOST_ASSERT((_data.size() + m_offset) <= m_size);
                put_at_offset(_data.c_str(), _size, 2 * sizeof (boost::uint16_t));
            }

            BasicBuffer::BasicBuffer(const BasicBuffer& _packet) :
            SharedConstBuffer(_packet)
            {
                get_at_offset(&m_id, sizeof (boost::uint16_t), sizeof (boost::uint16_t));
            }

			BasicBuffer::~BasicBuffer()
            {
            }

            BasicBuffer* BasicBuffer::make(boost::shared_ptr< std::vector<unsigned char> >& _data)
            {
                BasicBuffer* _temp = new BasicBuffer(_data, (boost::uint16_t)((*_data)[0]));
                _temp->get_at_offset(&(_temp->m_id), sizeof (boost::uint16_t), sizeof (boost::uint16_t));
                _temp->m_offset = 0;
                return _temp;
            }

            BasicBuffer* BasicBuffer::make(boost::uint16_t _size, boost::uint16_t _id, std::string& _data)
            {
                BasicBuffer* _temp = new BasicBuffer(_size);
                _temp->putId(_id);
                _temp->putData(_data);
                return _temp;
            }

            std::vector< unsigned char >& BasicBuffer::operator*()
            {
                return *m_data;
            }

            std::size_t BasicBuffer::getSize()
            {
                return size();
            }

            boost::uint16_t BasicBuffer::getId()
            {
                return m_id;
            }

            void BasicBuffer::putSize(boost::uint16_t _size)
            {
                put_at_offset(&_size, sizeof (boost::uint16_t), 0);
            }

            void BasicBuffer::putId(boost::uint16_t _id)
            {
                put_at_offset(&_id, sizeof (boost::uint16_t), sizeof (boost::uint16_t));
                m_id = _id;
            }

            void BasicBuffer::putData(std::string& _data)
            {
                put_at_offset(_data.c_str(), _data.size(), 2 * sizeof (boost::uint16_t));
            }

            void BasicBuffer::putData(std::string& _data, boost::uint16_t _size)
            {
                put_at_offset(_data.c_str(), _size, 2 * sizeof (boost::uint16_t) );
			}

		} //  namespace buffer
    } //  // namespace network
